<template>
  <div class="file-to-hex">
    <h3>文件转 16 进制数据流</h3>
    
    <!-- 文件选择区域 -->
    <div class="upload-area" @click="selectFile">
      <span>点击选择文件</span>
      <input
        type="file"
        ref="fileInput"
        class="file-input"
        @change="handleFileChange"
      >
    </div>
    
    <!-- 转换结果 -->
    <div v-if="fileInfo" class="result-section">
      <div class="file-info">
        <p>文件名: {{ fileInfo.name }}</p>
        <p>类型: {{ fileInfo.type }}</p>
        <p>大小: {{ formatSize(fileInfo.size) }} ({{ fileInfo.size }} 字节)</p>
        <p>16 进制长度: {{ hexData ? hexData.length : 0 }} 字符</p>
      </div>
      
      <!-- 16 进制数据展示 -->
      <div class="hex-data">
        <h4>16 进制数据流</h4>
        <div class="hex-display" v-if="hexData">
          <pre>{{ formattedHex }}</pre>
        </div>
        <button 
          @click="copyHex" 
          :disabled="!hexData"
          class="copy-btn"
        >
          复制 16 进制数据
        </button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fileInfo: null,  // 文件基本信息
      hexData: null    // 原始16进制字符串
    };
  },
  computed: {
    // 格式化16进制数据，每16字节换行，便于查看
    formattedHex() {
      if (!this.hexData) return '';
      
      let result = '';
      // 每两个字符代表一个字节，16字节就是32个字符
      for (let i = 0; i < this.hexData.length; i += 32) {
        // 截取32个字符(16字节)并添加换行
        result += this.hexData.substring(i, i + 32) + '\n';
      }
      return result;
    }
  },
  methods: {
    // 触发文件选择
    selectFile() {
      this.$refs.fileInput.click();
    },
    
    // 处理文件选择
    handleFileChange(e) {
      const file = e.target.files[0];
      if (!file) return;
      
      // 保存文件信息
      this.fileInfo = {
        name: file.name,
        type: file.type,
        size: file.size
      };
      
      // 转换为16进制
      this.convertToHex(file);
      
      // 重置输入，允许重复选择同一文件
      e.target.value = '';
    },
    
    // 将文件转换为16进制数据流
    convertToHex(file) {
      const reader = new FileReader();
      
      // 读取文件为ArrayBuffer(二进制缓冲区)
      reader.readAsArrayBuffer(file);
      
      reader.onload = (event) => {
        const arrayBuffer = event.target.result;
        const uint8Array = new Uint8Array(arrayBuffer);
        
        // 转换为16进制字符串
        let hexString = '';
        uint8Array.forEach(byte => {
          // 确保每个字节转换为两位16进制，不足的前面补0
          const hex = byte.toString(16).padStart(2, '0');
          hexString += hex;
        });
        
        this.hexData = hexString;
      };
      
      reader.onerror = () => {
        alert('文件读取失败，请重试');
      };
    },
    
    // 格式化文件大小
    formatSize(bytes) {
      if (bytes < 1024) return `${bytes} B`;
      if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
      return `${(bytes / 1048576).toFixed(1)} MB`;
    },
    
    // 复制16进制数据到剪贴板
    copyHex() {
      navigator.clipboard.writeText(this.hexData)
        .then(() => alert('16进制数据已复制到剪贴板'))
        .catch(() => alert('复制失败，请手动复制'));
    }
  }
};
</script>

<style scoped>
.file-to-hex {
  max-width: 800px;
  margin: 2rem auto;
  padding: 1.5rem;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  font-family: Arial, sans-serif;
}

.upload-area {
  border: 2px dashed #ccc;
  padding: 2rem;
  text-align: center;
  cursor: pointer;
  margin-bottom: 1.5rem;
  transition: all 0.3s;
}

.upload-area:hover {
  border-color: #42b983;
  background-color: #f9f9f9;
}

.file-input {
  display: none;
}

.result-section {
  margin-top: 1rem;
}

.file-info {
  padding: 1rem;
  background-color: #f5f5f5;
  border-radius: 4px;
  margin-bottom: 1rem;
}

.hex-data {
  margin-top: 1rem;
}

.hex-display {
  background-color: #2d2d2d;
  color: #a9b7c6;
  padding: 1rem;
  border-radius: 4px;
  overflow-x: auto;
  max-height: 300px;
}

pre {
  margin: 0;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
}

.copy-btn {
  margin-top: 1rem;
  padding: 0.5rem 1rem;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.copy-btn:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.copy-btn:hover:not(:disabled) {
  background-color: #359e6d;
}
</style>
